package com.kunbo.shop.service.impl.product;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Transient;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.kunbo.offer.dao.MaterialsDao;
import com.kunbo.offer.entity.ManHour;
import com.kunbo.offer.entity.Materials;
import com.kunbo.shop.controller.product.ProductController.ParamqQuerys;
import com.kunbo.shop.dao.product.ProductAssortPortDao;
import com.kunbo.shop.dao.product.ProductHalfProductDao;
import com.kunbo.shop.dao.product.ProductInfoDao;
import com.kunbo.shop.dao.product.ProductManHourDao;
import com.kunbo.shop.dao.product.ProductMaterialDao;
import com.kunbo.shop.dao.product.ProductParameterDao;
import com.kunbo.shop.dao.product.ProductStandardDao;
import com.kunbo.shop.dao.sort.ProductSortDao;
import com.kunbo.shop.dao.template.TemplateAssortPortDao;
import com.kunbo.shop.dao.template.TemplateHalfProductDao;
import com.kunbo.shop.dao.template.TemplateInfoDao;
import com.kunbo.shop.dao.template.TemplateManHourDao;
import com.kunbo.shop.dao.template.TemplateMaterialDao;
import com.kunbo.shop.dao.template.TemplateParameterDao;
import com.kunbo.shop.dao.template.TemplateStandardDao;
import com.kunbo.shop.entity.Product.ProductAssortPort;
import com.kunbo.shop.entity.Product.ProductHalfProduct;
import com.kunbo.shop.entity.Product.ProductInfo;
import com.kunbo.shop.entity.Product.ProductManHour;
import com.kunbo.shop.entity.Product.ProductMaterial;
import com.kunbo.shop.entity.Product.ProductParameter;
import com.kunbo.shop.entity.Product.ProductStandard;
import com.kunbo.shop.entity.sort.ProductSort;
import com.kunbo.shop.entity.sort.ProductSort.SORT_TYPE;
import com.kunbo.shop.entity.template.AttriType;
import com.kunbo.shop.entity.template.OptionType;
import com.kunbo.shop.entity.template.TemplateAssortPort;
import com.kunbo.shop.entity.template.TemplateHalfProduct;
import com.kunbo.shop.entity.template.TemplateInfo;
import com.kunbo.shop.entity.template.TemplateManHour;
import com.kunbo.shop.entity.template.TemplateMaterial;
import com.kunbo.shop.entity.template.TemplateParameter;
import com.kunbo.shop.entity.template.TemplateStandard;
import com.kunbo.shop.service.product.ProductService;
import com.shuohe.util.json.Json;
import com.shuohe.util.returnBean.ReturnBean;
import com.shuohe.util.string.QString;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import lombok.Data;

@Service
public class ProductServiceImpl implements ProductService{

	@Autowired ProductSortDao productSortDao;
	@Autowired ProductInfoDao productInfoDao;
	@Autowired ProductParameterDao productParameterDao;
	@Autowired ProductAssortPortDao productAssortPortDao;
	
	@Autowired ProductHalfProductDao productHalfProductDao;
	@Autowired ProductManHourDao productManHourDao;
	@Autowired ProductStandardDao productStandardDao;
	@Autowired ProductMaterialDao productMaterialDao;
	
	
	@Autowired  TemplateAssortPortDao 		templateAssortPortDao;
	@Autowired  TemplateHalfProductDao 		templateHalfProductDao;
	@Autowired  TemplateInfoDao 			templateInfoDao;
	@Autowired  TemplateManHourDao 			templateManHourDao;
	@Autowired  TemplateMaterialDao 		templateMaterialDao;
	@Autowired  TemplateParameterDao 		templateParameterDao;
	@Autowired  TemplateStandardDao 		templateStandardDao;
	   
	@Autowired MaterialsDao materialsDao;
	
	@Autowired JdbcTemplate jdbcTemplate;
	
	
	@Override
	@Transactional
	public ReturnBean insert(ProductSort productSort) {
		ReturnBean ret = new ReturnBean(false,"");
		//1、获取产品的上级，也就是产品线的信息
		ProductSort product_line = productSortDao.findById(productSort.getPid());
		if(product_line == null)		
		{		
			ret.setDescribe("系统找不到新建产品的产品线");
			return ret;
		}
		//2、找到产品线关联的所有的模板信息
		List<TemplateInfo> templateInfoList = templateInfoDao.findBySortId(product_line.getId());
		//3、保存产品
		productSort = productSortDao.save(productSort);
		//4、在产品概览表中创建模板相关的信息
//		List<ProductInfo> ProductInfoList = new ArrayList<ProductInfo>();
		for(TemplateInfo s:templateInfoList)
		{
			ProductInfo p = geProductInfoByTemplateInfo(productSort,s);
			productInfoDao.save(p);
			switch(s.getAttriType())
			{
				case HALF_PRODUCT:	//半成品
				{
					ProductHalfProduct productHalfProduct = getProductHalfProductByTemplateInfo(productSort,p,s);
					productHalfProductDao.save(productHalfProduct);
				}
				break;
				case PARAMETER:		//参数
				{
					ProductParameter productParameter = getProductParameterByTemplateInfo(productSort,p,s);
					productParameterDao.save(productParameter);
				}
				break;
				case STANDARD_PORT:	//标准品
				{
					ProductStandard productStandard = getProductStandardByTemplateInfo(productSort,p,s);
					productStandardDao.save(productStandard);
				}
				break;
				case MANHOUR:		//工时
				{
					ProductManHour productManHour = getProductManHourByTemplateInfo(productSort,p,s);
					productManHourDao.save(productManHour);
				}				
				break;
				case MATERIAL:		//材料	
				{
					ProductMaterial productMaterial = getProductMaterialByTemplateInfo(productSort,p,s);
					productMaterialDao.save(productMaterial);
				}
				break;
				case ASSORT_PORT:	//配套件
				{
					ProductAssortPort productAssortPort = getProductAssortPortByTemplateInfo(productSort,p,s);
					productAssortPortDao.save(productAssortPort);
				}
				break;
			}
		}
//		productInfoDao.save(ProductInfoList);
		return new ReturnBean(true,"save success");
	}
	
	@Override
	public ReturnBean checkRepeatProduct(ProductSort productSort)
	{
		
		List<ProductSort> list = productSortDao.findProductByProductNumber(productSort.getProductNumber());
		if(list==null) return new ReturnBean(true,"没有同名的产品");
		if(list.size()>0) return new ReturnBean(false,"已经有了相同编号的产品");
		else return new ReturnBean(true,"没有同名的产品");		
	}
	
	
	@Override
	public ReturnBean deleteById(String id) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	@Transactional
	public ReturnBean deleteBySortId(String sortId)
	{
		try
		{
			productInfoDao.deleteByProductId(sortId);
			productParameterDao.deleteByProductId(sortId);
			productAssortPortDao.deleteByProductId(sortId);
			
			productHalfProductDao.deleteByProductId(sortId);
			productManHourDao.deleteByProductId(sortId);
			productStandardDao.deleteByProductId(sortId);
			productMaterialDao.deleteByProductId(sortId);
			return new ReturnBean(true,"删除成功");
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return new ReturnBean(false,"删除失败");
		}
	}

	@Override
	public List<ProductInfoView> getProductInfoForTreeByProductId(String productId) {
		//1、获取所有的产品信息
		List<ProductInfo> l = productInfoDao.findByProductIdOrderByCalculateSequ(productId);
		
		//2、获取计算价格所需的参数
		List<ProductParameter> param_list = getProductParameterByProductId(productId);
		//3、获取计算价格所需的材料
		List<ProductMaterial> material_list = getProductMaterialByProductId(productId);
		//4、获取计算价格所需的半成品
		List<ProductHalfProduct> half_product_list = getHalfProductByProductId(productId);		
		//5、获取计算价格所需的标准品
		List<ProductStandard> productStandard_list = getProudctStandardByProductId(productId);
		//5、获取计算价格所需的配套件
		List<ProductAssortPort> productAssortPort_list = getProductAssortPortByProductId(productId);
		//6、获取计算价格所需的公式列表
		List<ProductManHour> productManHour_list = getProductManHourByProductId(productId);
		
		return getProductInfoForTreeByProductId(	
				l
				,param_list
				,material_list
				,half_product_list
				,productStandard_list
				,productAssortPort_list
				,productManHour_list);
	}
	
//	@Override
//	public List<ProductInfoView> getProductInfoForTreeByProductId(String productId) {
//		List<ProductInfo> l = productInfoDao.findByProductId(productId);
//		List<ProductInfoView> pfv = new ArrayList<ProductInfoView>();
//		for(ProductInfo p:l)
//		{
////			System.out.println("getProductInfoForTreeByProductId -- ");
//			switch(p.getAttriType())
//			{
//				case HALF_PRODUCT:	//半成品
//				{
//					ProductHalfProduct productHalfProduct = productHalfProductDao.findByProductInfoId(p.getId());
//					ProductInfoView f = new ProductInfoView();
////					f.setAssort_price(assort_price);//配件的价格
//					f.setAttriType(p.getAttriType());
////					f.setFormula(formula);//计算公式
//					f.setId(p.getId());
////					f.setNumber(number);//工时数量
//					f.setOptionType(productHalfProduct.getOptionType());
//					f.setPid(p.getPid());
//					f.setPrice(productHalfProduct.getPrice());//工时价格
//					f.setProductId(p.getProductId());
//					f.setSortId(p.getSortId());
//					f.setTemplateInfoId(p.getTemplateInfoId());
//					f.setText(p.getText());
//					f.setUnit(p.getUnit());
////					f.setUnitPrice(unitPrice);//工时单价&标准品单价
////					f.setUsage_amount(usage_amount);//使用量
////					f.setValue(value);//参数的实际值
//					f.setLevel(p.getLevel());
//					f.setFilter(p.isFilter());
//					f.setQuote(p.isQuote());
//					f.setProductCompId(productHalfProduct.getId());
//					pfv.add(f);
//				}
//				break;
//				case PARAMETER:		//参数
//				{				
//					ProductParameter productParameter = productParameterDao.findByProductInfoId(p.getId());
//					ProductInfoView f = new ProductInfoView();
////					f.setAssort_price(assort_price);//配件的价格
//					f.setAttriType(p.getAttriType());
////					f.setFormula(formula);//计算公式
//					f.setId(p.getId());
////					f.setNumber(number);//工时数量
////					f.setOptionType(productHalfProduct.getOptionType());
//					f.setPid(p.getPid());
////					f.setPrice(price);//工时价格
//					f.setProductId(p.getProductId());
//					f.setSortId(p.getSortId());
//					f.setTemplateInfoId(p.getTemplateInfoId());
//					f.setText(p.getText());
//					f.setUnit(p.getUnit());
////					f.setUnitPrice(unitPrice);//工时单价&标准品单价
////					f.setUsage_amount(usage_amount);//使用量
//					f.setValue(productParameter.getValue());//参数的实际值
//					f.setLevel(p.getLevel());
//					f.setFilter(p.isFilter());
//					f.setQuote(p.isQuote());
//					f.setProductCompId(productParameter.getId());
//					pfv.add(f);
//				}
//				break;
//				case STANDARD_PORT:	//标准品
//				{					
//					ProductStandard productStandard = productStandardDao.findByProductInfoId(p.getId());
//					ProductInfoView f = new ProductInfoView();
////					f.setAssort_price(assort_price);//配件的价格
//					f.setAttriType(p.getAttriType());
////					f.setFormula(formula);//计算公式
//					f.setId(p.getId());
////					f.setNumber(number);//工时数量
////					f.setOptionType(productHalfProduct.getOptionType());
//					f.setPid(p.getPid());
//					f.setPrice(productStandard.getUnitPrice());//工时价格
//					f.setProductId(p.getProductId());
//					f.setSortId(p.getSortId());
//					f.setTemplateInfoId(p.getTemplateInfoId());
//					f.setText(p.getText());
//					f.setUnit(p.getUnit());
////					f.setUnitPrice(productStandard.getUnitPrice());//工时单价&标准品单价
////					f.setUsage_amount(usage_amount);//使用量
////					f.setValue(productParameter.getValue());//参数的实际值
//					f.setLevel(p.getLevel());
//					f.setFilter(p.isFilter());
//					f.setQuote(p.isQuote());
//					f.setProductCompId(productStandard.getId());
//					pfv.add(f);
//				}
//				break;
//				case MANHOUR:		//工时
//				{
//					ProductManHour productManHour = productManHourDao.findByProductInfoId(p.getId());
//					ProductInfoView f = new ProductInfoView();
////					f.setAssort_price(assort_price);//配件的价格
//					f.setAttriType(p.getAttriType());
////					f.setFormula(formula);//计算公式
//					f.setId(p.getId());
//					f.setNumber(productManHour.getNumber());//工时数量
////					f.setOptionType(productHalfProduct.getOptionType());
//					f.setPid(p.getPid());
//					f.setPrice(productManHour.getPrice());//工时价格
//					f.setProductId(p.getProductId());
//					f.setSortId(p.getSortId());
//					f.setTemplateInfoId(p.getTemplateInfoId());
//					f.setText(productManHour.getText());
////					System.out.println("productManHour.getManhourName() = "+productManHour.getManhourName());
//					f.setUnit(p.getUnit());
//					f.setUnitPrice(productManHour.getUnitPrice());//工时单价&标准品单价
////					f.setUsage_amount(usage_amount);//使用量
////					f.setValue(productParameter.getValue());//参数的实际值
//					f.setLevel(p.getLevel());
//					f.setFilter(p.isFilter());
//					f.setQuote(p.isQuote());
//					f.setProductCompId(productManHour.getId());
//					pfv.add(f);
//				}				
//				break;
//				case MATERIAL:		//材料	
//				{
//
//					ProductMaterial productMaterial = productMaterialDao.findByProductInfoId(p.getId());
//					ProductInfoView f = new ProductInfoView();
////					f.setAssort_price(assort_price);//配件的价格
//					f.setAttriType(p.getAttriType());
////					f.setFormula(p.getf);//计算公式
//					f.setId(p.getId());
////					f.setNumber(number);//工时数量
////					f.setOptionType(productHalfProduct.getOptionType());
//					f.setPid(p.getPid());
//					f.setPrice(productMaterial.getDefaultPrice());//工时价格
//					f.setProductId(p.getProductId());
//					f.setSortId(p.getSortId());
//					f.setTemplateInfoId(p.getTemplateInfoId());
//					f.setText(p.getText());
//					f.setUnit(p.getUnit());
////					f.setUnitPrice(unitPrice);//工时单价
//					f.setUsage_amount(productMaterial.getUsage_amount());//使用量
////					f.setValue(value);//参数的实际值
//					f.setLevel(p.getLevel());
//					f.setFilter(p.isFilter());
//					f.setQuote(p.isQuote());
//					f.setProductCompId(productMaterial.getId());
//					pfv.add(f);
//				}
//				break;
//				case ASSORT_PORT:	//配套件
//				{		
//					ProductAssortPort productAssortPort = productAssortPortDao.findByProductInfoId(p.getId());
//					ProductInfoView f = new ProductInfoView();
////					f.setAssort_price(productAssortPort.getAssort_price());//配件的价格
//					f.setAttriType(p.getAttriType());
////					f.setFormula(p.getf);//计算公式
//					f.setId(p.getId());
////					f.setNumber(number);//工时数量
////					f.setOptionType(productAssortPort.getOptionType());
//					f.setPid(p.getPid());
//					f.setPrice(productAssortPort.getAssort_price());//工时价格&配套件价格&标准件价格
//					f.setProductId(p.getProductId());
//					f.setSortId(p.getSortId());
//					f.setTemplateInfoId(p.getTemplateInfoId());
//					f.setText(p.getText());
//					f.setUnit(p.getUnit());
////					f.setUnitPrice(unitPrice);//工时单价
////					f.setUsage_amount(productMaterial.getUsage_amount());//使用量
////					f.setValue(value);//参数的实际值
//					f.setLevel(p.getLevel());
//					f.setFilter(p.isFilter());
//					f.setQuote(p.isQuote());
//					f.setProductCompId(productAssortPort.getId());
//					pfv.add(f);
//				}
//				break;
//			}
//		}
//	
//		return getChildsManyGroup(pfv,"-");
//	}

	@Data
	public class ProductInfoView{
		String id;//主键uuid
		
		String productId;//产品本身的编码
		
		String pid;
		
		String text;
		
		String sortId;//产品模型的编号
		
		String templateInfoId; //产品模型信息的父类编码
		
		//产品上具体组件的编码，关系到后期组件本身调整带来的价格变更
		//对应于ProductAssortPort.id、ProductHalfProduct.id  
		//ProductHalfProduct.id  ProductManHour.id  ProductMaterial.id  ProductParameter.id
		//ProductStandard.id
		String productCompId;
		
		String unit;
		
		AttriType attriType;
		
		OptionType optionType;
			
		List<ProductInfoView> children;
		
		//参数
		double value;	//参数的实际值
		
		//配套件
		double assort_price;	//配件的价格
		
		//工时
		double unitPrice;	//工时单价&标准品单价
		
		double number;		//工时数量
		
		double price;		//工时价格
		
		//材料
		double usage_amount;	//使用量

		String formula;//计算公式
		
		int level;
		
		boolean isFilter;	//是否作为筛选项
		
		boolean isQuote;	//是否作为报价项
	
	}
	
	
	
	public static List<ProductInfoView> getChildsManyGroup(List<ProductInfoView> list,String pid)
	{  
		List<ProductInfoView> arr = new ArrayList<ProductInfoView>();  
		for(ProductInfoView location : list)
		{  
		    if(pid.equals(location.getPid()))
		    {  
		        location.setChildren(getChildsManyGroup(list, location.getTemplateInfoId()));    
		        arr.add(location);   
		    }  
		}  
		return arr;  
	}

	@Override
	public ProductParameter findParameterByProductInfoId(String productInfoId) {
		return productParameterDao.findByProductInfoId(productInfoId);
	}

	@Override
	public ProductParameter saveProductParameter(ProductParameter productParameter) {
		return productParameterDao.save(productParameter);
	}

	@Override
	public ProductAssortPort findAssortPortByProductInfoId(String productInfoId) {
		return productAssortPortDao.findByProductInfoId(productInfoId);
	}

	@Override
	public ProductAssortPort saveProductAssortPort(ProductAssortPort productAssortPort) {
		return productAssortPortDao.save(productAssortPort);
	}

	@Override
	public ProductHalfProduct findHalfProductByProductInfoId(String productInfoId) {
		return productHalfProductDao.findByProductInfoId(productInfoId);
	}

	@Override
	public ProductHalfProduct saveProductHalfProduct(ProductHalfProduct productHalfProduct) {
		return productHalfProductDao.save(productHalfProduct);
	}

	@Override
	public ProductManHour findManHourByProductInfoId(String productInfoId) {
		return productManHourDao.findByProductInfoId(productInfoId);
	}

	@Override
	public ProductManHour saveProductManHour(ProductManHour productManHour) {
		return productManHourDao.save(productManHour);
	}

	@Override
	public ProductMaterial findMaterialByProductInfoId(String productInfoId) {
		return productMaterialDao.findByProductInfoId(productInfoId);
	}

	@Override
	public ProductMaterial saveProductMaterial(ProductMaterial productMaterial) {
		return productMaterialDao.save(productMaterial);
	}

	@Override
	public ProductStandard findStandardByProductInfoId(String productInfoId) {
		return productStandardDao.findByProductInfoId(productInfoId);
	}

	@Override
	public ProductStandard saveProductStandard(ProductStandard productStandard) {
		return productStandardDao.save(productStandard);
	}

	@Override
	public String findMaterialTemplateFormulaByProductInfoId(String productInfoId) {
		// TODO Auto-generated method stub
		
		if(StrUtil.isBlank(productInfoId)) return null;
		
		QueryRunner qRunner = new QueryRunner();   
		String sql = "";
		sql += " SELECT";
		sql += " 	db_offer_template_material.formula";
		sql += " FROM";
		sql += " 	db_offer_product_material";
		sql += " LEFT JOIN db_offer_product_info ON db_offer_product_info.id = db_offer_product_material.productInfoId";
		sql += " LEFT JOIN db_offer_template_material ON db_offer_template_material.templateInfoId = db_offer_product_info.templateInfoId";
		sql += " WHERE";
		sql += " 	db_offer_product_material.productInfoId = '"+productInfoId+"'";

		List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
		if(list!=null)
		{
			if(list.size()!=0)
			{
				return (String) list.get(0).get("formula");
			}
		}
		return null;
	}
	
	public List<ProductParameter> getProductParameterByProductId(String productId)
	{
		
		//判断productId是否为空
		if(QString.isNull(productId)) return null;
		
		String sql1 = "";
		sql1 += " SELECT";
		sql1 += " 	db_offer_product_parameter.*";
		sql1 += " FROM";
		sql1 += " 	db_offer_product_info";
		sql1 += " LEFT JOIN db_offer_product_parameter on db_offer_product_parameter.productInfoId = db_offer_product_info.id";
		sql1 += " WHERE";
		sql1 += " 	db_offer_product_info.productId = '"+productId+"'";
		sql1 += " 	and db_offer_product_info.attriType = "+ AttriType.PARAMETER.ordinal()+"";

		List<ProductParameter> pp_list = jdbcTemplate.query(sql1, new RowMapper<ProductParameter>() {
			@Override
			public ProductParameter mapRow(ResultSet rs, int rowNum) throws SQLException {
				ProductParameter productParameter = new ProductParameter();
				productParameter.setId(rs.getString("id"));
				productParameter.setIsfilter(rs.getBoolean("isfilter"));
				productParameter.setProductInfoId(rs.getString("productInfoId"));
				productParameter.setSort_id(rs.getString("sort_id"));
				productParameter.setText(rs.getString("text"));
				productParameter.setUnit(rs.getString("unit"));
				productParameter.setValue(rs.getDouble("value"));
				productParameter.setProductId(rs.getString("productId"));
				return productParameter;
			}
		});
//		System.out.println("pp_list = "+ Json.toJson(pp_list));
		return pp_list;
	}	

	/** 
	* @Description: 根据产品编码获得该产品的所有原材料（只用于计算，获取参数不全）
	* @Title: getProductMaterialByProductSort 
	* @param productInfoId
	* @return List<ProductMaterial>
	* @author qin
	* @date 2018年12月1日上午11:53:08
	*/ 
	public List<ProductMaterial> getProductMaterialByProductId(String productId)
	{
		
		//判断productId是否为空
		if(QString.isNull(productId)) return null;
		
		String sql1 = "";
		sql1 += " SELECT";
		sql1 += " 	db_offer_product_material.*";
		sql1 += " FROM";
		sql1 += " 	db_offer_product_info";
		sql1 += " LEFT JOIN db_offer_product_material on db_offer_product_material.productInfoId = db_offer_product_info.id";
		sql1 += " WHERE";
		sql1 += " 	db_offer_product_info.productId = '"+productId+"'";
		sql1 += " 	and db_offer_product_info.attriType = "+ AttriType.MATERIAL.ordinal()+"";

		List<ProductMaterial> pp_list = jdbcTemplate.query(sql1, new RowMapper<ProductMaterial>() {
			@Override
			public ProductMaterial mapRow(ResultSet rs, int rowNum) throws SQLException {
				ProductMaterial productMaterial = new ProductMaterial();
				productMaterial.setDefaultMateId(rs.getString("defaultMateId"));
				productMaterial.setDefaultMateName(rs.getString("defaultMateName"));
				productMaterial.setDefaultMatePrice(rs.getDouble("defaultMatePrice"));
				productMaterial.setDefaultPrice(rs.getDouble("defaultPrice"));
				productMaterial.setFormula(rs.getString("formula"));
				productMaterial.setId(rs.getString("id"));
				productMaterial.setMaterialId(rs.getString("materialId"));
				productMaterial.setProductId(rs.getString("productId"));
				productMaterial.setProductInfoId(rs.getString("productInfoId"));
				productMaterial.setSortId(rs.getString("sortId"));
				productMaterial.setText(rs.getString("text"));
				productMaterial.setUnit(rs.getString("unit"));
				productMaterial.setUnitPrice(rs.getDouble("unitPrice"));
				productMaterial.setUsage_amount(rs.getDouble("usage_amount"));			
				return productMaterial;
			}
		});
//		System.out.println("pp_list = "+ Json.toJson(pp_list));
		return pp_list;
	}
	
	
	/** 
	 * 根据产品编码获得该产品的所有半成品 的名称和价格（只用于计算，获取参数不全）
	* @Description: TODO 
	* @Title: getHalfProductByProductId 
	* @param productId
	* @return List<ProductHalfProduct>
	* @author qin
	* @date 2018年12月12日下午5:59:47
	*/ 
	public List<ProductHalfProduct> getHalfProductByProductId(String productId)
	{		
		//判断productId是否为空
		if(QString.isNull(productId)) return null;
		
		String sql1 = "";
		sql1 += " SELECT";
		sql1 += " 	db_offer_product_halfproduct.*";
		sql1 += " FROM";
		sql1 += " 	db_offer_product_info";
		sql1 += " LEFT JOIN db_offer_product_halfproduct on db_offer_product_halfproduct.productInfoId = db_offer_product_info.id";
		sql1 += " WHERE";
		sql1 += " 	db_offer_product_info.productId = '"+productId+"'";
		sql1 += " 	and db_offer_product_info.attriType = "+ AttriType.HALF_PRODUCT.ordinal()+"";

		List<ProductHalfProduct> pp_list = jdbcTemplate.query(sql1, new RowMapper<ProductHalfProduct>() {
			@Override
			public ProductHalfProduct mapRow(ResultSet rs, int rowNum) throws SQLException {
				ProductHalfProduct productHalfProduct = new ProductHalfProduct();
				productHalfProduct.setId(rs.getString("id"));
				productHalfProduct.setFormula(rs.getString("formula"));
				productHalfProduct.setOptionType(OptionType.values()[rs.getInt("optionType")]);
				productHalfProduct.setPrice(rs.getDouble("price"));
				productHalfProduct.setProductId(rs.getString("productId"));
				productHalfProduct.setSortId(rs.getString("sortId"));
				productHalfProduct.setText(rs.getString("text"));
				productHalfProduct.setUnit(rs.getString("unit"));
				productHalfProduct.setProductInfoId(rs.getString("productInfoId"));
				return productHalfProduct;
			}
		});
//		System.out.println("pp_list = "+ Json.toJson(pp_list));
		return pp_list;
	}

	
	/** 
	 * 根据产品编码获得该产品的所有半成品 的名称和价格（只用于计算，获取参数不全）
	* @Description: TODO 
	* @Title: getHalfProductByProductId 
	* @param productId
	* @return List<ProductHalfProduct>
	* @author qin
	* @date 2018年12月12日下午5:59:47
	*/ 
	public List<ProductStandard> getProudctStandardByProductId(String productId)
	{		
		//判断productId是否为空
		if(QString.isNull(productId)) return null;
		
		String sql1 = "";
		sql1 += " SELECT";
		sql1 += " 	db_offer_product_standard.*";
		sql1 += " FROM";
		sql1 += " 	db_offer_product_info";
		sql1 += " LEFT JOIN db_offer_product_standard on db_offer_product_standard.productInfoId = db_offer_product_info.id";
		sql1 += " WHERE";
		sql1 += " 	db_offer_product_info.productId = '"+productId+"'";
		sql1 += " 	and db_offer_product_info.attriType = "+ AttriType.STANDARD_PORT.ordinal()+"";

		List<ProductStandard> pp_list = jdbcTemplate.query(sql1, new RowMapper<ProductStandard>() {
			@Override
			public ProductStandard mapRow(ResultSet rs, int rowNum) throws SQLException {
				ProductStandard productStandard = new ProductStandard();
				productStandard.setId(rs.getString("id"));
				productStandard.setProductId(rs.getString("productId"));
				productStandard.setProductInfoId(rs.getString("productInfoId"));
				productStandard.setSortId(rs.getString("sortId"));
				productStandard.setStandardId(rs.getString("standardId"));
				productStandard.setStandardName(rs.getString("standardName"));
				productStandard.setStandardSortId(rs.getString("standardSortId"));
				productStandard.setText(rs.getString("text"));
				productStandard.setUnitPrice(rs.getDouble("unitPrice"));
				return productStandard;
			}
		});
//		System.out.println("pp_list = "+ Json.toJson(pp_list));
		return pp_list;
	}
	
	
	public List<ProductAssortPort> getProductAssortPortByProductId(String productId)
	{		
		//判断productId是否为空
		if(QString.isNull(productId)) return null;
		
		String sql1 = "";
		sql1 += " SELECT";
		sql1 += " 	db_offer_product_assortport.*";
		sql1 += " FROM";
		sql1 += " 	db_offer_product_info";
		sql1 += " LEFT JOIN db_offer_product_assortport on db_offer_product_assortport.productInfoId = db_offer_product_info.id";
		sql1 += " WHERE";
		sql1 += " 	db_offer_product_info.productId = '"+productId+"'";
		sql1 += " 	and db_offer_product_info.attriType = "+ AttriType.ASSORT_PORT.ordinal()+"";

		List<ProductAssortPort> pp_list = jdbcTemplate.query(sql1, new RowMapper<ProductAssortPort>() {
			@Override
			public ProductAssortPort mapRow(ResultSet rs, int rowNum) throws SQLException {
				ProductAssortPort productAssortPort = new ProductAssortPort();
				productAssortPort.setAssort_price(rs.getDouble("assort_price"));
				productAssortPort.setId(rs.getString("id"));
				productAssortPort.setProductId(rs.getString("productId"));
				productAssortPort.setProductInfoId(rs.getString("productInfoId"));
				productAssortPort.setSortId(rs.getString("sortId"));
				productAssortPort.setText(rs.getString("text"));
				return productAssortPort;
			}
		});
//		System.out.println("pp_list = "+ Json.toJson(pp_list));
		return pp_list;
	}
	
	@Override
	public List<ProductAssortPort> getProductAssortPortByTemplateInfoId(String templateInfoId)
	{		
		//判断productId是否为空
		if(QString.isNull(templateInfoId)) return null;
		
		String sql1 = "";
		sql1 += " SELECT";
		sql1 += " 	db_offer_product_assortport.*";
		sql1 += " FROM";
		sql1 += " 	db_offer_product_info";
		sql1 += " LEFT JOIN db_offer_product_assortport on db_offer_product_assortport.productInfoId = db_offer_product_info.id";
		sql1 += " WHERE";
		sql1 += " 	db_offer_product_info.templateInfoId = '"+templateInfoId+"'";

		List<ProductAssortPort> pp_list = jdbcTemplate.query(sql1, new RowMapper<ProductAssortPort>() {
			@Override
			public ProductAssortPort mapRow(ResultSet rs, int rowNum) throws SQLException {
				ProductAssortPort productAssortPort = new ProductAssortPort();
				productAssortPort.setAssort_price(rs.getDouble("assort_price"));
				productAssortPort.setId(rs.getString("id"));
				productAssortPort.setProductId(rs.getString("productId"));
				productAssortPort.setProductInfoId(rs.getString("productInfoId"));
				productAssortPort.setSortId(rs.getString("sortId"));
				productAssortPort.setText(rs.getString("text"));
				productAssortPort.setUnit_price(rs.getDouble("unit_price"));
				productAssortPort.setNum(rs.getInt("num"));
				return productAssortPort;
			}
		});
		return pp_list;
	}
	
	
	
	
	
	public List<ProductManHour> getProductManHourByProductId(String productId)
	{		
		//判断productId是否为空
		if(QString.isNull(productId)) return null;
		
		String sql1 = "";
		sql1 += " SELECT";
		sql1 += " 	db_offer_product_manhour.*";
		sql1 += " FROM";
		sql1 += " 	db_offer_product_info";
		sql1 += " LEFT JOIN db_offer_product_manhour on db_offer_product_manhour.productInfoId = db_offer_product_info.id";
		sql1 += " WHERE";
		sql1 += " 	db_offer_product_info.productId = '"+productId+"'";
		sql1 += " 	and db_offer_product_info.attriType = "+ AttriType.MANHOUR.ordinal()+"";

		List<ProductManHour> pp_list = jdbcTemplate.query(sql1, new RowMapper<ProductManHour>() {
			@Override
			public ProductManHour mapRow(ResultSet rs, int rowNum) throws SQLException {
				ProductManHour productManHour = new ProductManHour();
				productManHour.setId(rs.getString("id"));
				productManHour.setManhourId(rs.getString("manhourId"));
				productManHour.setManhourName(rs.getString("manhourName"));
				productManHour.setNumber(rs.getDouble("number"));
				productManHour.setPrice(rs.getDouble("price"));
				productManHour.setProductId(rs.getString("productId"));
				productManHour.setProductInfoId(rs.getString("productInfoId"));
				productManHour.setSortId(rs.getString("sortId"));
				productManHour.setText(rs.getString("text"));
				productManHour.setUnit(rs.getString("unit"));
				productManHour.setUnitPrice(rs.getDouble("unitPrice"));				
				return productManHour;
			}
		});
//		System.out.println("pp_list = "+ Json.toJson(pp_list));
		return pp_list;
	}
	
	
	/** 
	* @Description: 重构计算公式，带入参数、原材料等输入参数。 
	* @Title: constructionJsFormula 
	* @param formula
	* @param param_list
	* @param material_list
	* @return String
	* @author qin
	* @date 2018年12月1日上午11:57:47
	*/ 
	public String constructionJsFormula(
			String formula,
			List<ProductParameter> param_list,
			List<ProductMaterial> material_list)
	{
		String js = "";
		String params_js = "";

		for(ProductParameter p:param_list)
		{
			String r = "var "+p.getText()+" = "+p.getValue()+";\r\n";
			params_js += r;
		}
		for(ProductMaterial p:material_list)
		{
			String r = "var "+p.getText()+" = "+p.getUsage_amount()+";\r\n";
			params_js += r;
		}
		js = ""
		+ "function priceCalculation()\r\n"  
		+ "{\r\n" 
		+ params_js
		+ "return ("+formula+");\r\n" 
		+ "}"
		+ "";
		
		return js;
	}

	@Override
	public double calculatorMaterialUseage(String productInfoId) {
		
		String productId = findProductIdByProductInfoId(productInfoId);
		double result = 0;
		
		//1、获取材料的计算公式
		String formula = findMaterialTemplateFormulaByProductInfoId(productInfoId);
				
		//有计算公式则根据计算公式进行计算,无计算公式直接获取用量，并计算价格
		if(formula != null && !formula.equals(""))
		{
			//2、获取计算材料所需的所有的参数属性
			List<ProductParameter> param_list = getProductParameterByProductId(productId);
			
			List<ProductMaterial> material_list = getProductMaterialByProductId(productId);
			//3、重构计算公式，为其带入参数值与函数结构
			String construction =  constructionJsFormula(formula,param_list,material_list);
			System.out.print(construction);
			System.out.println("");
			
			//4、创建JS引擎
			ScriptEngineManager manager = new ScriptEngineManager();   
			ScriptEngine engine = manager.getEngineByName("javascript");   	
			Invocable invoke = (Invocable)engine;    				
			

			//5、加载计算公式
			try {
				engine.eval(construction);
				result = (Double)invoke.invokeFunction("priceCalculation");
				System.out.print("result = "+result);
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ScriptException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}		
			//6、将计算结果保存至该产品材料数据库
			ProductMaterial productMaterial = productMaterialDao.findByProductInfoId(productInfoId);
			productMaterial.setUsage_amount(result);			
			//8、将用量和物料单价相乘，得到物料的默认价格
			productMaterial.setDefaultPrice(result*productMaterial.getDefaultMatePrice());
			productMaterialDao.save(productMaterial);			
		}
		else
		{
			ProductMaterial productMaterial = productMaterialDao.findByProductInfoId(productInfoId);			
			//7、将用量和物料单价相乘，得到物料的默认价格
			productMaterial.setDefaultPrice(productMaterial.getUsage_amount()*productMaterial.getDefaultMatePrice());
			productMaterialDao.save(productMaterial);
		}		
		

		
		return result;
	}
	
	
	/** 
	* @Description: 半成品价格计算计算公式装配方法 
	* @Title: constructionJsFormula 
	* @param formula
	* @param param_list
	* @param material_list
	* @return String
	* @author qin
	* @date 2018年12月12日下午6:17:04
	*/ 
	public String constructionHalfProductJsFormula(
			String formula,
			List<ProductParameter> param_list,
			List<ProductMaterial> material_list,
			List<ProductHalfProduct> half_product_list,
			List<ProductStandard> productStandard_list,
			List<ProductAssortPort> productAssortPort_list,
			List<ProductManHour> productManHour_list)
	{
		String js = "";
		String params_js = "";

		for(ProductParameter p:param_list)
		{
			String r = "var "+p.getText()+" = "+p.getValue()+";\r\n";
			params_js += r;
		}
		for(ProductMaterial p:material_list)
		{
			String r = "var "+p.getText()+" = "+p.getDefaultPrice()+";\r\n";
			params_js += r;
		}
		for(ProductHalfProduct p:half_product_list)
		{
			String r = "var "+p.getText()+" = "+p.getPrice()+";\r\n";
			params_js += r;
		}	
		for(ProductStandard p:productStandard_list)
		{
			if(p.getText()!=null&&!p.getText().equals(""))
			{
				String r = "var "+p.getText()+" = "+p.getUnitPrice()+";\r\n";
				params_js += r;
			}
		}	
		for(ProductAssortPort p:productAssortPort_list)
		{
			if(p.getText()!=null&&!p.getText().equals(""))
			{
				String r = "var "+p.getText()+" = "+p.getAssort_price()+";\r\n";
				params_js += r;
			}
		}	
		for(ProductManHour p:productManHour_list)
		{			
			if(p.getText()!=null&&!p.getText().equals(""))
			{
				String r = "var "+p.getText()+" = "+p.getPrice()+";\r\n";
				params_js += r;
			}
		}			
		js = ""
		+ "function priceCalculation()\r\n"  
		+ "{\r\n" 
		+ params_js
		+ "return ("+formula+");\r\n" 
		+ "}"
		+ "";
		
		return js;
	}
	
	@Override
	public double calculatorHalfProductPrice(String productInfoId)
	{
		String productId = findProductIdByProductInfoId(productInfoId);
		
		//1、获取计算公式
		ProductHalfProduct halfProduct = findHalfProductByProductInfoId(productInfoId);
		//2、获取计算价格所需的参数
		List<ProductParameter> param_list = getProductParameterByProductId(productId);
		//3、获取计算价格所需的材料
		List<ProductMaterial> material_list = getProductMaterialByProductId(productId);
		//4、获取计算价格所需的半成品
		List<ProductHalfProduct> half_product_list = getHalfProductByProductId(productId);		
		
		List<ProductStandard> productStandard_list = getProudctStandardByProductId(productId);
		
		List<ProductAssortPort> productAssortPort_list = getProductAssortPortByProductId(productId);
		
		List<ProductManHour> productManHour_list = getProductManHourByProductId(productId);
		
		//5、重构计算公式，为其带入参数值与函数结构
		
		if(halfProduct.getFormula() == null || halfProduct.getFormula().equals("")) return 0;
		
		String construction =  constructionHalfProductJsFormula(halfProduct.getFormula()
				,param_list
				,material_list
				,half_product_list
				,productStandard_list
				,productAssortPort_list
				,productManHour_list);
		System.out.print(construction);
		
		//6、创建JS引擎
		ScriptEngineManager manager = new ScriptEngineManager();   
		ScriptEngine engine = manager.getEngineByName("javascript");   	
		Invocable invoke = (Invocable)engine;    				
		
		double result = 0;
		//7、加载计算公式
		try {
			engine.eval(construction);
			result = (Double)invoke.invokeFunction("priceCalculation");
			System.out.print("result = "+result);
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ScriptException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//8、保存本次计算结果
		halfProduct.setPrice(result);
		productHalfProductDao.save(halfProduct);
		
		return result;		
	}
	

	@Override
	public ReturnBean calculatorPorductPrice(String productId) {
		//1、获取产品的所有材料Info
		List<ProductInfo> l = productInfoDao.findByProductIdOrderByCalculateSequ(productId);
		//2、遍历所有的部件，如果为材料则对其进行运算
		for(ProductInfo p:l)
		{
			if(p.getAttriType() == AttriType.MATERIAL)
			{
				calculatorMaterialUseage(p.getId());
			}
			if(p.getAttriType() == AttriType.HALF_PRODUCT)
			{
				calculatorHalfProductPrice(p.getId());
			}
		}
		return new ReturnBean(true,"");
	}

	@Override
	public String findProductIdByProductInfoId(String productInfoId) {
		ProductInfo productInfo = productInfoDao.findById(productInfoId);
		return productInfo.getProductId();
	}

	@Override
	public ReturnBean calculatorPorductPriceByProductId(String productId) {		
		return null;
	}

	
	public double calculatorHalfProductPrice(
			String formula,
			List<ProductParameter> param_list,
			List<ProductMaterial> material_list,
			List<ProductHalfProduct> half_product_list,
			List<ProductStandard> productStandard_list,
			List<ProductAssortPort> productAssortPort_list,
			List<ProductManHour> productManHour_list)
	{
		String construction =  constructionHalfProductJsFormula(
				formula
				,param_list
				,material_list
				,half_product_list
				,productStandard_list
				,productAssortPort_list
				,productManHour_list);
		
		
		System.out.print(construction);
		
		//6、创建JS引擎
		ScriptEngineManager manager = new ScriptEngineManager();   
		ScriptEngine engine = manager.getEngineByName("javascript");   	
		Invocable invoke = (Invocable)engine;    				
		
		double result = 0;
		//7、加载计算公式
		try {
			engine.eval(construction);
			result = (Double)invoke.invokeFunction("priceCalculation");
//			System.out.print("result = "+result);
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ScriptException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return result;	
	}
	
	
	
	@Override
	public List<ProductInfoView> getPorductTreeListByNewMaterial(String productId, String materialId) {

		//1、获取所有的产品信息
		List<ProductInfo> l = productInfoDao.findByProductIdOrderByCalculateSequ(productId);
		
		//2、获取计算价格所需的参数
		List<ProductParameter> param_list = getProductParameterByProductId(productId);
		//3、获取计算价格所需的材料
		List<ProductMaterial> material_list = getProductMaterialByProductId(productId);
		//4、获取计算价格所需的半成品
		List<ProductHalfProduct> half_product_list = getHalfProductByProductId(productId);		
		//5、获取计算价格所需的标准品
		List<ProductStandard> productStandard_list = getProudctStandardByProductId(productId);
		//5、获取计算价格所需的配套件
		List<ProductAssortPort> productAssortPort_list = getProductAssortPortByProductId(productId);
		//6、获取计算价格所需的公式列表
		List<ProductManHour> productManHour_list = getProductManHourByProductId(productId);
		
		//7、根据材料编码获取材料
		Materials materials = materialsDao.findById(materialId);
		
		//按照顺序计算各部分部件的参数以及价格
		//先计算部件的参数，再计算价格
		//8.1、计算原材料的价格（这里只变更了材料，所以用量是没有变更的）,这里用ProductInfo遍历是因为他携带了level属性，
		//能够基本保证运算顺序的正确
		for(ProductInfo pi:l)
		{
			if(pi.getAttriType() == AttriType.MATERIAL)
			{
				for(int i=0;i<material_list.size();i++)
				{
					if(pi.getId().equals(material_list.get(i).getProductInfoId()))
					{
						ProductMaterial _productMaterial = material_list.get(i);
						_productMaterial.setDefaultMateId(materials.getId());
						_productMaterial.setDefaultMateName(materials.getName());
						_productMaterial.setDefaultMatePrice(materials.getPrice());
						_productMaterial.setDefaultPrice(_productMaterial.getUsage_amount()*materials.getPrice());						
						material_list.set(i, _productMaterial);
						System.out.println("material_list = i = "+i+"  "+Json.toJson(_productMaterial));
						break;
					}
				}
			}
		}
		System.out.println("material_list = "+Json.toJson(material_list));
		System.out.println("ProductInfo = "+Json.toJson(l));
		System.out.println("half_product_list = "+Json.toJson(half_product_list));
		//8.1、计算半成品的价格
		for(ProductInfo pi:l)
		{
			if(pi.getAttriType() == AttriType.HALF_PRODUCT)
			{
				for(int i=0;i<half_product_list.size();i++)
				{
					if(pi.getId().equals(half_product_list.get(i).getProductInfoId()))
					{
						ProductHalfProduct _productHalfProduct = half_product_list.get(i);
						System.out.println("ProductHalfProduct = "+Json.toJson(_productHalfProduct));
						if(_productHalfProduct.getFormula() != null && !"".equals(_productHalfProduct.getFormula()))
						{
							System.out.println("getFormula = "+_productHalfProduct.getFormula());
							double price = calculatorHalfProductPrice(
								_productHalfProduct.getFormula()
								,param_list
								,material_list
								,half_product_list
								,productStandard_list
								,productAssortPort_list
								,productManHour_list);
							_productHalfProduct.setPrice(price);
							half_product_list.set(i, _productHalfProduct);
							break;
						}
					}				
				}
			}
		}		
		return getProductInfoForTreeByProductId(	
				l
				,param_list
				,material_list
				,half_product_list
				,productStandard_list
				,productAssortPort_list
				,productManHour_list);
	}
	public List<ProductInfoView> getProductInfoForTreeByProductId(		
			List<ProductInfo> product_info_list,
			List<ProductParameter> param_list,
			List<ProductMaterial> material_list,
			List<ProductHalfProduct> half_product_list,
			List<ProductStandard> productStandard_list,
			List<ProductAssortPort> productAssortPort_list,
			List<ProductManHour> productManHour_list) {
		List<ProductInfoView> pfv = new ArrayList<ProductInfoView>();
		for(ProductInfo p:product_info_list)
		{
			switch(p.getAttriType())
			{
				case HALF_PRODUCT:	//半成品
				{
//					System.out.println("HALF_PRODUCT = "+Json.toJson(half_product_list));
					
					for(ProductHalfProduct _temp:half_product_list)
					{
//						System.out.println("_temp ="+_temp.getProductInfoId()+"  p = "+p.getId());
						if(_temp.getProductInfoId().equals(p.getId()))
						{
//							System.out.println("ProductHalfProduct.ProductInfoId"+_temp.getProductInfoId());
							ProductInfoView f = new ProductInfoView();
//							f.setAssort_price(assort_price);//配件的价格
							f.setAttriType(p.getAttriType());
//							f.setFormula(formula);//计算公式
							f.setId(p.getId());
//							f.setNumber(number);//工时数量
							f.setOptionType(_temp.getOptionType());
							f.setPid(p.getPid());
							f.setPrice(_temp.getPrice());//工时价格
							f.setProductId(p.getProductId());
							f.setSortId(p.getSortId());
							f.setTemplateInfoId(p.getTemplateInfoId());
							f.setText(p.getText());
							f.setUnit(p.getUnit());
//							f.setUnitPrice(unitPrice);//工时单价&标准品单价
//							f.setUsage_amount(usage_amount);//使用量
//							f.setValue(value);//参数的实际值
							f.setLevel(p.getLevel());
							f.setFilter(p.isFilter());
							f.setQuote(p.isQuote());
							pfv.add(f);							
							break;
						}
					}					
				}
				break;
				case PARAMETER:		//参数
				{				
					for(ProductParameter _temp:param_list)
					{
						if(_temp.getProductInfoId().equals(p.getId()))
						{
							ProductInfoView f = new ProductInfoView();
//							f.setAssort_price(assort_price);//配件的价格
							f.setAttriType(p.getAttriType());
//							f.setFormula(formula);//计算公式
							f.setId(p.getId());
//							f.setNumber(number);//工时数量
//							f.setOptionType(productHalfProduct.getOptionType());
							f.setPid(p.getPid());
//							f.setPrice(price);//工时价格
							f.setProductId(p.getProductId());
							f.setSortId(p.getSortId());
							f.setTemplateInfoId(p.getTemplateInfoId());
							f.setText(p.getText());
							f.setUnit(p.getUnit());
//							f.setUnitPrice(unitPrice);//工时单价&标准品单价
//							f.setUsage_amount(usage_amount);//使用量
							f.setValue(_temp.getValue());//参数的实际值
							f.setLevel(p.getLevel());
							f.setFilter(p.isFilter());
							f.setQuote(p.isQuote());
							pfv.add(f);
							break;							
						}
					}
				}
				break;
				case STANDARD_PORT:	//标准品
				{					
					for(ProductStandard _temp:productStandard_list)
					{
						if(_temp.getProductInfoId().equals(p.getId()))
						{
							ProductInfoView f = new ProductInfoView();
//							f.setAssort_price(assort_price);//配件的价格
							f.setAttriType(p.getAttriType());
//							f.setFormula(formula);//计算公式
							f.setId(p.getId());
//							f.setNumber(number);//工时数量
//							f.setOptionType(productHalfProduct.getOptionType());
							f.setPid(p.getPid());
							f.setPrice(_temp.getUnitPrice());//工时价格
							f.setProductId(p.getProductId());
							f.setSortId(p.getSortId());
							f.setTemplateInfoId(p.getTemplateInfoId());
							f.setText(p.getText());
							f.setUnit(p.getUnit());
//							f.setUnitPrice(productStandard.getUnitPrice());//工时单价&标准品单价
//							f.setUsage_amount(usage_amount);//使用量
//							f.setValue(productParameter.getValue());//参数的实际值
							f.setLevel(p.getLevel());
							f.setFilter(p.isFilter());
							f.setQuote(p.isQuote());
							pfv.add(f);
							break;							
						}
					}					
				}
				break;
				case MANHOUR:		//工时
				{
					for(ProductManHour _temp:productManHour_list)
					{
						if(_temp.getProductInfoId().equals(p.getId()))
						{
							ProductInfoView f = new ProductInfoView();
//							f.setAssort_price(assort_price);//配件的价格
							f.setAttriType(p.getAttriType());
//							f.setFormula(formula);//计算公式
							f.setId(p.getId());
							f.setNumber(_temp.getNumber());//工时数量
//							f.setOptionType(productHalfProduct.getOptionType());
							f.setPid(p.getPid());
							f.setPrice(_temp.getPrice());//工时价格
							f.setProductId(p.getProductId());
							f.setSortId(p.getSortId());
							f.setTemplateInfoId(p.getTemplateInfoId());
							f.setText(_temp.getText());
//							System.out.println("productManHour.getManhourName() = "+productManHour.getManhourName());
							f.setUnit(p.getUnit());
							f.setUnitPrice(_temp.getUnitPrice());//工时单价&标准品单价
//							f.setUsage_amount(usage_amount);//使用量
//							f.setValue(productParameter.getValue());//参数的实际值
							f.setLevel(p.getLevel());
							f.setFilter(p.isFilter());
							f.setQuote(p.isQuote());
							pfv.add(f);
							break;							
						}
					}					
				}				
				break;
				case MATERIAL:		//材料	
				{
					for(ProductMaterial _temp:material_list)
					{
						if(_temp.getProductInfoId().equals(p.getId()))
						{
							ProductInfoView f = new ProductInfoView();
//							f.setAssort_price(assort_price);//配件的价格
							f.setAttriType(p.getAttriType());
//							f.setFormula(p.getf);//计算公式
							f.setId(p.getId());
//							f.setNumber(number);//工时数量
//							f.setOptionType(productHalfProduct.getOptionType());
							f.setPid(p.getPid());
							f.setPrice(_temp.getDefaultPrice());//工时价格
							f.setProductId(p.getProductId());
							f.setSortId(p.getSortId());
							f.setTemplateInfoId(p.getTemplateInfoId());
							f.setText(p.getText());
							f.setUnit(p.getUnit());
//							f.setUnitPrice(unitPrice);//工时单价
							f.setUsage_amount(_temp.getUsage_amount());//使用量
//							f.setValue(value);//参数的实际值
							f.setLevel(p.getLevel());
							f.setFilter(p.isFilter());
							f.setQuote(p.isQuote());
							pfv.add(f);
							break;							
						}
					}					
				}
				break;
				case ASSORT_PORT:	//配套件
				{		
					for(ProductAssortPort _temp:productAssortPort_list)
					{
						if(_temp.getProductInfoId().equals(p.getId()))
						{
							ProductInfoView f = new ProductInfoView();
//							f.setAssort_price(productAssortPort.getAssort_price());//配件的价格
							f.setAttriType(p.getAttriType());
//							f.setFormula(p.getf);//计算公式
							f.setId(p.getId());
//							f.setNumber(number);//工时数量
//							f.setOptionType(productAssortPort.getOptionType());
							f.setPid(p.getPid());
							f.setPrice(_temp.getAssort_price());//工时价格&配套件价格&标准件价格
							f.setProductId(p.getProductId());
							f.setSortId(p.getSortId());
							f.setTemplateInfoId(p.getTemplateInfoId());
							f.setText(p.getText());
							f.setUnit(p.getUnit());
//							f.setUnitPrice(unitPrice);//工时单价
//							f.setUsage_amount(productMaterial.getUsage_amount());//使用量
//							f.setValue(value);//参数的实际值
							f.setLevel(p.getLevel());
							f.setFilter(p.isFilter());
							f.setQuote(p.isQuote());
							pfv.add(f);
							break;
						}
					}				
				}
				break;
			}
		}				
		return getChildsManyGroup(pfv,"-");
	}

	@Override
	public List<String> getProductParametersByTemplateInfoId(String templateInfoId) {
		//判断productId是否为空
		if(QString.isNull(templateInfoId)) return null;
		
		String sql = "";
		sql += " SELECT";
		sql += " 	db_offer_product_parameter.`value`";
		sql += " FROM";
		sql += " 	db_offer_template_parameter";
		sql += " LEFT JOIN db_offer_template_info ON db_offer_template_info.id = db_offer_template_parameter.templateInfoId";
		sql += " LEFT JOIN db_offer_product_info ON db_offer_product_info.templateInfoId = db_offer_template_info.id";
		sql += " LEFT JOIN db_offer_product_parameter ON db_offer_product_parameter.productInfoId = db_offer_product_info.id";
		sql += " WHERE";
		sql += " 	db_offer_template_parameter.templateInfoId = '"+templateInfoId+"'";
		sql += " GROUP BY db_offer_product_parameter.`value`";


		List<String> pp_list = jdbcTemplate.query(sql, new RowMapper<String>() {
			@Override
			public String mapRow(ResultSet rs, int rowNum) throws SQLException {
				String ret = rs.getString("value");	
				return ret;
			}
		});
//		System.out.println("pp_list = "+ Json.toJson(pp_list));
		return pp_list;
	}

	@Override
	public List<Map<String,String>> getProductByLineAndParams(String productLine, List<ParamqQuerys> paramqQuerys) {

		
		String sql = "";
		sql += " SELECT";
		sql += " 	db_offer_sort.id,";
		sql += " 	db_offer_sort.text";
		sql += " FROM";
		sql += " 	db_offer_product_parameter";
		sql += " LEFT JOIN db_offer_sort on db_offer_sort.id = db_offer_product_parameter.productId";
		sql += " WHERE";
		sql += " 	db_offer_sort.pid = '"+productLine+"'";
		sql += " GROUP BY db_offer_sort.id";
		System.out.println(sql);
		List<String> proIds = new ArrayList<String>();
		List<Map<String,String>> pp_list = jdbcTemplate.query(sql, new RowMapper<Map<String,String>>() {
			@Override
			public Map<String, String> mapRow(ResultSet rs, int rowNum) throws SQLException {
				Map<String,String> n = new HashMap<String,String>();
				n.put(rs.getString("id"), rs.getString("text"));
				proIds.add(rs.getString("id"));
				return n;
			}
		});		
		if(paramqQuerys == null || paramqQuerys.size()==0){
			return pp_list;
		}
		//1、先获取风机大类下所有的风机编号    pp_list (已完成)
		//2、获取风机参数条件
		List<ProductParameter> list = productParameterDao.findByProductIds(proIds);
		if(list == null || list.size()==0){
			return pp_list;
		}
		
		//3、数据列转行
		List<Map<String, String>> listParameter = new ArrayList<Map<String,String>>();
		List<String> keyList = new ArrayList<String>();
		for (ProductParameter parameter  : list) {
			if(!keyList.contains(parameter.getProductId())){
				keyList.add(parameter.getProductId());
			}
		}
		DecimalFormat df = new DecimalFormat("######0.00");   
		for (String tempKey : keyList) {
			Map<String, String> map = new HashMap<String, String>();
			String strValue = "";
			for (ProductParameter parameter  : list) {
				if(tempKey.equals(parameter.getProductId())){
					strValue +=parameter.getText()+df.format(parameter.getValue()).toString();
				}
			}
			map.put(tempKey, strValue);
			listParameter.add(map);
		}
		//4、对不符合条件的数据进行剔除。 
		List<String> allProductId = new ArrayList<String>();
		for (Map<String, String> tempMap : listParameter) {
			boolean isTrue = true;
			for(String key : tempMap.keySet()){
				String parValue = tempMap.get(key);
				for(int i=0;i<paramqQuerys.size();i++){
					if(!parValue.contains(paramqQuerys.get(i).getKey()+df.format(Convert.toDouble(paramqQuerys.get(i).getValue())).toString())){
						isTrue = false;
					}
				}
			}
			if(isTrue){
				for(String key : tempMap.keySet()){
					allProductId.add(key);
				}				
			}
		}
		/*for (ProductParameter pro : list) {
			for(int i=0;i<paramqQuerys.size();i++){
				if(pro.getText().equals(paramqQuerys.get(i).getKey()) && pro.getValue() == Convert.toDouble(paramqQuerys.get(i).getValue())){
					if(!allProductId.contains(pro.getProductId())){
						allProductId.add(pro.getProductId());
					}
				}
			}
		}*/
		//输出
		for (String tem : allProductId) {
			System.err.println("条件符合的产品ID是："+tem);
		}
		List<Map<String,String>> pp_list_2 = new ArrayList<Map<String,String>>();
		for (Map<String, String> map : pp_list) {
			for (String str : allProductId) {
				for(String key : map.keySet()){
					if(str.equals(key) && !pp_list_2.contains(map)){
						System.err.println("key="+key+",value="+map.get(key));
						pp_list_2.add(map);
					}
				}
			}
		}
		System.err.println("符合的有："+pp_list_2.size());
		return pp_list_2;
		
	}

	
	@Override
	@Transactional
	public boolean reCalculatorProductManHour(ManHour manHour) {
		//1、找出所有的产品下的产品工时数据
		List<ProductManHour> pmh_l = productManHourDao.findByManhourId(manHour.getId());
		//2、遍历重新计算所有工时的数据
		for(int i=0;i<pmh_l.size();i++)
		{
			ProductManHour pmh = pmh_l.get(i);
			pmh.setManhourName(manHour.getName());
			pmh.setUnitPrice(manHour.getPrice());
			pmh.setPrice(manHour.getPrice()*pmh.getNumber());			
			pmh_l.set(i, pmh);
		}
		productManHourDao.save(pmh_l);
		return true;
	}

	@Override
	public ProductStandard getProductStandardByTemplateInfo(ProductSort productSort,ProductInfo p,TemplateInfo s) {
		TemplateStandard templateStandard = templateStandardDao.findBytemplateInfoId(s.getId());
		System.out.println("templateStandard findBytemplateInfoId = "+ s.getId());
		System.out.println(Json.toJson(templateStandard));
		ProductStandard productStandard = new ProductStandard();
		productStandard.setStandardSortId(templateStandard.getStandardSortId());
		productStandard.setUnitPrice(0);
		//productStandard.setId(id);
		productStandard.setProductInfoId(p.getId());
		productStandard.setSortId(s.getSortId());
		productStandard.setProductId(productSort.getId());									
//		productStandard.setStandardId(standardId);
		productStandard.setText(templateStandard.getText());
		productStandard.setStandardName(templateStandard.getStandardName());
		//productStandard.setUnitPrice(templateStandard.getun);
		productStandard.setTemplateId(templateStandard.getId());
		return productStandard;
	}

	@Override
	public ProductMaterial getProductMaterialByTemplateInfo(ProductSort productSort,ProductInfo p,TemplateInfo s) {
		TemplateMaterial templateMaterial = templateMaterialDao.findBytemplateInfoId(s.getId());
		ProductMaterial productMaterial = new ProductMaterial();
		//productMaterial.setId(id);
		//productMaterial.setMaterialId(materialId);
		productMaterial.setProductInfoId(p.getId());
		productMaterial.setSortId(s.getSortId());
		productMaterial.setProductId(productSort.getId());									
		productMaterial.setText(templateMaterial.getText());
		productMaterial.setUnit(templateMaterial.getUnit());
		productMaterial.setUnitPrice(templateMaterial.getUnitPrice());
		productMaterial.setFormula(templateMaterial.getFormula());
		productMaterial.setTemplateId(templateMaterial.getId());
		return productMaterial;
	}

	@Override
	public ProductManHour getProductManHourByTemplateInfo(ProductSort productSort,ProductInfo p,TemplateInfo s) {
		TemplateManHour templateManHour = templateManHourDao.findBytemplateInfoId(s.getId());
		System.out.println("templateManHour = "+Json.toJson(templateManHour));
		ProductManHour productManHour = new ProductManHour();
		productManHour.setManhourId(templateManHour.getManhourId());//用户还未配置，不需设置
		productManHour.setNumber(0);			 //初始化一个价格，防止数据库错误
		productManHour.setPrice(0);			 	 //初始化一个价格，防止数据库错误
		productManHour.setProductInfoId(p.getId());
		productManHour.setSortId(s.getSortId());
		productManHour.setProductId(productSort.getId());									
		productManHour.setText(templateManHour.getText());
		productManHour.setUnit(templateManHour.getUnit());
		productManHour.setUnitPrice(templateManHour.getUnitPrice());//初始化一个价格，防止数据库错误
		productManHour.setManhourName(templateManHour.getManhourName());
		productManHour.setTemplateId(templateManHour.getId());
		return productManHour;
	}

	@Override
	public ProductAssortPort getProductAssortPortByTemplateInfo(ProductSort productSort,ProductInfo p,TemplateInfo s) {
		TemplateAssortPort templateAssortPort = templateAssortPortDao.findBytemplateInfoId(s.getId());	
		ProductAssortPort productAssortPort = new ProductAssortPort();
		productAssortPort.setAssort_price(0);	//初始化一个价格，防止数据库错误
		productAssortPort.setProductInfoId(p.getId());
		productAssortPort.setSortId(s.getSortId());
		productAssortPort.setProductId(productSort.getId());									
		productAssortPort.setText(templateAssortPort.getText());
		productAssortPort.setNum(templateAssortPort.getNum());
		productAssortPort.setTemplateId(templateAssortPort.getId());
		return productAssortPort;
	}

	@Override
	public ProductHalfProduct getProductHalfProductByTemplateInfo(ProductSort productSort,ProductInfo p,TemplateInfo s) {
		TemplateHalfProduct templateHalfProduct = templateHalfProductDao.findBytemplateInfoId(s.getId());
		ProductHalfProduct productHalfProduct = new ProductHalfProduct();
		productHalfProduct.setFormula(templateHalfProduct.getFormula());
		productHalfProduct.setOptionType(templateHalfProduct.getOptionType());
		productHalfProduct.setPrice(0);
		productHalfProduct.setProductInfoId(p.getId());
		productHalfProduct.setSortId(s.getSortId());
		productHalfProduct.setProductId(productSort.getId());
		productHalfProduct.setText(templateHalfProduct.getText());
		productHalfProduct.setUnit(templateHalfProduct.getUnit());
		productHalfProduct.setTemplateId(templateHalfProduct.getId());
		return productHalfProduct;
	}


	@Override
	public ProductParameter getProductParameterByTemplateInfo(ProductSort productSort,ProductInfo p,TemplateInfo s) {
		TemplateParameter templateParameter = templateParameterDao.findBytemplateInfoId(s.getId());
		ProductParameter productParameter = new ProductParameter();
		productParameter.setIsfilter(templateParameter.isIsfilter());
		productParameter.setProductInfoId(p.getId());
		productParameter.setTemplateId(templateParameter.getId());
		productParameter.setSort_id(s.getSortId());
		productParameter.setProductId(productSort.getId());					
		productParameter.setText(templateParameter.getText());
		productParameter.setUnit(templateParameter.getUnit());
		productParameter.setValue(0);
		return productParameter;
	}

	@Override
	public ProductInfo geProductInfoByTemplateInfo(ProductSort productSort, TemplateInfo s) {
		ProductInfo p = new ProductInfo();
		p.setAttriType(s.getAttriType());
		p.setOptionType(s.getOptionType());
		p.setPid(s.getPid());
		p.setSortId(s.getSortId());
		p.setTemplateInfoId(s.getId());
		p.setText(s.getText());
		p.setUnit(s.getUnit());
		p.setProductId(productSort.getId());
		p.setLevel(s.getLevel());
		p.setFilter(s.isFilter());
		p.setQuote(s.isQuote());
		p.setCalculateSequ(s.getCalculateSequ());
		return p;
	}

	@Override
	public ReturnBean copyProduct(String productId, String productNumber, String text) {
		// 通过产品编号找到这个产品
		ProductSort entity = productSortDao.findById(productId);
		if(entity == null){
			return new ReturnBean(false,"无法找到这个产品编号的产品");
		}
		else
		{
			ProductSort p = new ProductSort();
			p.setPid(entity.getPid());
			p.setText(text);
			p.setSort_type(SORT_TYPE.PRODUCT);
			p.setProductNumber(productNumber);
			p.setResponsible_id(entity.getResponsible_id());
			p.setResponsible_name(entity.getResponsible_name());
			productSortDao.save(p);
			
			List<ProductInfo> productInfoList =  productInfoDao.findByProductId(productId);
			for(ProductInfo productInfo:productInfoList)
			{
				ProductInfo newProductInfo = new ProductInfo();
				newProductInfo.setAttriType(productInfo.getAttriType());
				newProductInfo.setCalculateSequ(productInfo.getCalculateSequ());
//				newProductInfo.setChildren(children);
				newProductInfo.setFilter(productInfo.isFilter());
				newProductInfo.setLevel(productInfo.getLevel());
				newProductInfo.setOptionType(productInfo.getOptionType());
				newProductInfo.setPid(productInfo.getPid());
				newProductInfo.setProductId(p.getId());
				newProductInfo.setQuote(productInfo.isQuote());
				newProductInfo.setSortId(p.getPid());
				newProductInfo.setTemplateInfoId(productInfo.getTemplateInfoId());
				newProductInfo.setText(productInfo.getText());
				newProductInfo.setUnit(productInfo.getUnit());
				productInfoDao.save(newProductInfo);
				
				if(productInfo.getAttriType() == AttriType.ASSORT_PORT)
				{
					ProductAssortPort newProductAssortPort = new ProductAssortPort();
					ProductAssortPort productAssortPort = productAssortPortDao.findByProductInfoId(productInfo.getId());
					newProductAssortPort.setAssort_price(productAssortPort.getAssort_price());
					newProductAssortPort.setNum(productAssortPort.getNum());
					newProductAssortPort.setProductId(p.getId());
					newProductAssortPort.setProductInfoId(newProductInfo.getId());
					newProductAssortPort.setSortId(p.getPid());
					newProductAssortPort.setTemplateId(productAssortPort.getTemplateId());
					newProductAssortPort.setText(productAssortPort.getText());
					newProductAssortPort.setUnit_price(productAssortPort.getUnit_price());
					productAssortPortDao.save(newProductAssortPort);
				}
				if(productInfo.getAttriType() == AttriType.HALF_PRODUCT)
				{
					ProductHalfProduct newProductHalfProduct = new ProductHalfProduct();
					ProductHalfProduct productHalfProduct = productHalfProductDao.findByProductInfoId(productInfo.getId());
					newProductHalfProduct.setFormula(productHalfProduct.getFormula());
					newProductHalfProduct.setOptionType(productHalfProduct.getOptionType());
					newProductHalfProduct.setPrice(productHalfProduct.getPrice());
					newProductHalfProduct.setProductId(p.getId());
					newProductHalfProduct.setProductInfoId(newProductInfo.getId());
					newProductHalfProduct.setSortId(p.getPid());
					newProductHalfProduct.setTemplateId(productHalfProduct.getTemplateId());
					newProductHalfProduct.setText(productHalfProduct.getText());
					newProductHalfProduct.setUnit(productHalfProduct.getUnit());
					productHalfProductDao.save(newProductHalfProduct);
				}
				if(productInfo.getAttriType() == AttriType.MANHOUR)
				{
					ProductManHour newProductManHour = new ProductManHour();
					ProductManHour productManHour = productManHourDao.findByProductInfoId(productInfo.getId());
					newProductManHour.setManhourId(productManHour.getManhourId());
					newProductManHour.setManhourName(productManHour.getManhourName());
					newProductManHour.setNumber(productManHour.getNumber());
					newProductManHour.setPrice(productManHour.getPrice());
					newProductManHour.setProductId(p.getId());
					newProductManHour.setProductInfoId(newProductInfo.getId());
					newProductManHour.setSortId(p.getPid());
					newProductManHour.setTemplateId(productManHour.getTemplateId());
					newProductManHour.setText(productManHour.getText());
					newProductManHour.setUnit(productManHour.getUnit());
					newProductManHour.setUnitPrice(productManHour.getUnitPrice());
					productManHourDao.save(newProductManHour);
				}
				if(productInfo.getAttriType() == AttriType.MATERIAL)
				{
					ProductMaterial newProductMaterial = new ProductMaterial();
					ProductMaterial productMaterial = productMaterialDao.findByProductInfoId(productInfo.getId());
					newProductMaterial.setDefaultMateId(productMaterial.getDefaultMateId());
					newProductMaterial.setDefaultMateName(productMaterial.getDefaultMateName());
					newProductMaterial.setDefaultMatePrice(productMaterial.getDefaultMatePrice());
					newProductMaterial.setDefaultPrice(productMaterial.getDefaultPrice());
					newProductMaterial.setFormula(productMaterial.getFormula());
//					newProductMaterial.setId(id);
					newProductMaterial.setMaterialId(productMaterial.getMaterialId());
					newProductMaterial.setProductId(p.getId());
					newProductMaterial.setProductInfoId(newProductInfo.getId());
					newProductMaterial.setSortId(p.getPid());
					newProductMaterial.setTemplateId(productMaterial.getTemplateId());
					newProductMaterial.setText(productMaterial.getText());
					newProductMaterial.setUnit(productMaterial.getUnit());
					newProductMaterial.setUnitPrice(productMaterial.getUnitPrice());
					newProductMaterial.setUsage_amount(productMaterial.getUsage_amount());					
					productMaterialDao.save(newProductMaterial);
				}
				if(productInfo.getAttriType() == AttriType.PARAMETER)
				{
					ProductParameter newProductParameter = new ProductParameter();
					ProductParameter productParameter = productParameterDao.findByProductInfoId(productInfo.getId());
					newProductParameter.setIsfilter(productParameter.isIsfilter());
					newProductParameter.setProductId(p.getId());
					newProductParameter.setProductInfoId(newProductInfo.getId());
					newProductParameter.setSort_id(p.getPid());
					newProductParameter.setTemplateId(productParameter.getTemplateId());
					newProductParameter.setText(productParameter.getText());
					newProductParameter.setUnit(productParameter.getUnit());
					newProductParameter.setValue(productParameter.getValue());
					productParameterDao.save(newProductParameter);
				}
				if(productInfo.getAttriType() == AttriType.STANDARD_PORT)
				{
					ProductStandard newProductStandard = new ProductStandard();
					ProductStandard productStandard = productStandardDao.findByProductInfoId(productInfo.getId());
//					newProductStandard.setId(id);
					newProductStandard.setProductId(p.getId());
					newProductStandard.setProductInfoId(newProductInfo.getId());
					newProductStandard.setSortId(p.getPid());
					newProductStandard.setStandardId(productStandard.getStandardId());
					newProductStandard.setStandardName(productStandard.getStandardName());
					newProductStandard.setStandardSortId(productStandard.getStandardSortId());
					newProductStandard.setTemplateId(productStandard.getTemplateId());
					newProductStandard.setText(productStandard.getText());
					newProductStandard.setUnitPrice(productStandard.getUnitPrice());
					productStandardDao.save(newProductStandard);
				}
				
			}
			//将备份出来的产品重新计划一次
			calculatorPorductPrice(p.getId());
			return new ReturnBean(true,"复制成功");
		}
		// 为这个产品添加所有的产品属性
	}

	@Override
	public ReturnBean updateAllProductByTemplateChange(String sortId) {
		// TODO Auto-generated method stub
		
		//找到所有这个模型下所包含的呃产品列表
		List<ProductSort> productList = productSortDao.findByPid(sortId);
		for(ProductSort p:productList)
		{
			calculatorPorductPrice(p.getId());
		}
		return new ReturnBean(true,"计算成功");
	}


	
	

}
